<template>
    <!--地图挂载dom-->
    <div id="map">
    </div>
</template>

<script>
    //引入依赖
    import Map from 'ol/Map';
    import OSMXML from 'ol/format/OSMXML';
    import VectorSource from 'ol/source/Vector';
    import View from 'ol/View';
    import {Circle as CircleStyle, Fill, Stroke, Style} from 'ol/style';
    import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer';
    import OSM from 'ol/source/OSM'
    import {bbox as bboxStrategy} from 'ol/loadingstrategy';
    import {transformExtent} from 'ol/proj';
    export default {
        name: "XmlLayer",
        mounted() {
            let map = null;
            //定义样式，使用正则表达式匹配的样式
            const styles = {
                'amenity': {
                    'parking': new Style({
                        stroke: new Stroke({
                            color: 'rgba(170, 170, 170, 1.0)',
                            width: 1,
                        }),
                        fill: new Fill({
                            color: 'rgba(170, 170, 170, 0.3)',
                        }),
                    }),
                },
                'building': {
                    '.*': new Style({
                        zIndex: 100,
                        stroke: new Stroke({
                            color: 'rgba(246, 99, 79, 1.0)',
                            width: 1,
                        }),
                        fill: new Fill({
                            color: 'rgba(246, 99, 79, 0.3)',
                        }),
                    }),
                },
                'highway': {
                    'service': new Style({
                        stroke: new Stroke({
                            color: 'rgba(255, 255, 255, 1.0)',
                            width: 2,
                        }),
                    }),
                    '.*': new Style({
                        stroke: new Stroke({
                            color: 'rgba(255, 255, 255, 1.0)',
                            width: 3,
                        }),
                    }),
                },
                'landuse': {
                    'forest|grass|allotments': new Style({
                        stroke: new Stroke({
                            color: 'rgba(140, 208, 95, 1.0)',
                            width: 1,
                        }),
                        fill: new Fill({
                            color: 'rgba(140, 208, 95, 0.3)',
                        }),
                    }),
                },
                'natural': {
                    'tree': new Style({
                        image: new CircleStyle({
                            radius: 2,
                            fill: new Fill({
                                color: 'rgba(140, 208, 95, 1.0)',
                            }),
                            stroke: null,
                        }),
                    }),
                },
            };
            //xml同样是矢量数据源，因此也需要使用矢量数据加载xml矢量图层
            const vectorSource = new VectorSource({
                format: new OSMXML(),//使用osm的xml格式加载矢量数据
                loader: function (extent, resolution, projection, success, failure) {
                    //将数据范围从原投影转换到目标投影
                    const epsg4326Extent = transformExtent(extent, projection, 'EPSG:4326');
                    //创建ajax的请求对象
                    const client = new XMLHttpRequest();
                    //发送post请求
                    client.open('POST', 'https://overpass-api.de/api/interpreter');
                    //脸上链接之后监听数据加载情况
                    client.addEventListener('load', function () {
                        console.log(client.responseText)
                        //加载回来的xml数据,使用xml的数据格式转换出来
                        const features = new OSMXML().readFeatures(client.responseText, {
                            featureProjection: map.getView().getProjection(),
                        });
                        //将要素数据存储到矢量数据源中
                        vectorSource.addFeatures(features);
                        success(features);
                    });
                    client.addEventListener('error', failure);
                    //查询参数的拼接
                    const query =
                        '(node(' +
                        epsg4326Extent[1] +
                        ',' +
                        Math.max(epsg4326Extent[0], -180) +
                        ',' +
                        epsg4326Extent[3] +
                        ',' +
                        Math.min(epsg4326Extent[2], 180) +
                        ');rel(bn)->.foo;way(bn);node(w)->.foo;rel(bw););out meta;';
                    //发送查询的请求
                    client.send(query);
                },
                //数据加载的bbox规则
                strategy: bboxStrategy,
            });

            //将数据源的数据存储到矢量图层中
            const vector = new VectorLayer({
                source: vectorSource,
                style: function (feature) {
                    for (const key in styles) {
                        const value = feature.get(key);
                        if (value !== undefined) {
                            for (const regexp in styles[key]) {//通过正则表达式匹配样式
                                if (new RegExp(regexp).test(value)) {
                                    return styles[key][regexp];
                                }
                            }
                        }
                    }
                    return null;
                },
            });


            const raster = new TileLayer({
                source: new OSM()//加载OpenStreetMap
            });

            map = new Map({
                layers: [raster, vector],
                target: document.getElementById('map'),
                view: new View({
                    center: [739218, 5906096],
                    maxZoom: 19,
                    zoom: 17,
                }),
            });
        },
        methods: {
        }
    }
</script>

<style scoped>

</style>